﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvdDonk.Bomberman.Screens.Base;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;

namespace MvdDonk.Bomberman.Screens
{
    class GameplayScreen : GameScreen
    {
        SpriteFont gameFont;

        float pauseAlpha;


        // Global content.
        private SpriteFont hudFont;

        private Texture2D winOverlay;
        private Texture2D loseOverlay;
        private Texture2D diedOverlay;

        // Meta-level game state.
        private int levelIndex = -1;
        private Level level;
        private bool wasContinuePressed;

        // When the time remaining is less than the warning time, it blinks on the hud
        private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);

        // The number of levels in the Levels directory of our content. We assume that
        // levels in our content are 0-based and that all numbers under this constant
        // have a level file present. This allows us to not need to check for the file
        // or handle exceptions, both of which can add unnecessary time to level loading.
        private const int numberOfLevels = 3;


        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            level = new Level("Map1");
        }

        public override void LoadContent()
        {
            base.LoadContent();

            // Load fonts
            hudFont = Bomberman.Instance.ResourceManager.RequestFont("Fonts/Hud");

            // Load overlay textures
            winOverlay = Bomberman.Instance.ResourceManager.RequestTexture("Overlays/you_win");
            loseOverlay = Bomberman.Instance.ResourceManager.RequestTexture("Overlays/you_lose");
            diedOverlay = Bomberman.Instance.ResourceManager.RequestTexture("Overlays/you_died");

            //Known issue that you get exceptions if you use Media PLayer while connected to your PC
            //See http://social.msdn.microsoft.com/Forums/en/windowsphone7series/thread/c8a243d2-d360-46b1-96bd-62b1ef268c66
            //Which means its impossible to test this from VS.
            //So we have to catch the exception and throw it away
            try
            {
                MediaPlayer.IsRepeating = true;
                MediaPlayer.Play(Bomberman.Instance.ResourceManager.RequestSong("Sounds/Music"));
            }
            catch { }

            //LoadNextLevel();

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            Bomberman.Instance.ResetElapsedTime();
        }

        public override void UnloadContent()
        {
            //TODO unload all resources?
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            Bomberman.Instance.EntityManager.Update(gameTime, level.Map);

            if (IsActive)
            {
                level.Update(gameTime);
            }
        }

        public override void HandleInput(GameTime gameTime)
        {
            //if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            //{
            //    ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            //}
            //else
            //{

            bool continuePressed = Bomberman.Instance.InputManager.KeyDown(Keys.Space);

            // Perform the appropriate action to advance the game and
            // to get the player back to playing.
            if (!wasContinuePressed && continuePressed)
            {
                //if (!level.Player.IsAlive)
                //{
                //    level.StartNewLife();
                //}
                //else if (level.TimeRemaining == TimeSpan.Zero)
                //{
                //    if (level.ReachedExit)
                //        LoadNextLevel();
                //    else
                //        ReloadCurrentLevel();
                //}
            }

            wasContinuePressed = continuePressed;
            //}
        }


        //private void LoadNextLevel()
        //{
        //    // move to the next level
        //    levelIndex = (levelIndex + 1) % numberOfLevels;

        //    // Unloads the content for the current level before loading the next one.
        //    if (level != null)
        //        level.Dispose();

        //    // Load the level.
        //    string levelPath = string.Format("Content/Levels/{0}.txt", levelIndex);
        //    using (Stream fileStream = TitleContainer.OpenStream(levelPath))
        //        level = new Level(ScreenManager.Game.Services, fileStream, levelIndex);
        //}

        //private void ReloadCurrentLevel()
        //{
        //    --levelIndex;
        //    LoadNextLevel();
        //}

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            // This game has a blue background. Why? Because!
            Bomberman.Instance.GraphicsDevice.Clear(ClearOptions.Target, Color.CornflowerBlue, 0, 0);

            spriteBatch.Begin();

            level.Draw(gameTime, spriteBatch);

            DrawHud(spriteBatch);

            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);
                ScreenManager.FadeBackBufferToBlack(spriteBatch, alpha);
            }
        }


        private void DrawHud(SpriteBatch spriteBatch)
        {
            Rectangle titleSafeArea = Bomberman.Instance.GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
            Color timeColor;
            if (level.TimeRemaining > WarningTime ||
                level.IsFinished ||
                (int)level.TimeRemaining.TotalSeconds % 2 == 0)
            {
                timeColor = Color.Yellow;
            }
            else
            {
                timeColor = Color.Red;
            }
            DrawShadowedString(spriteBatch, hudFont, timeString, hudLocation, timeColor);

            // Draw score
            float timeHeight = hudFont.MeasureString(timeString).Y;
            DrawShadowedString(spriteBatch, hudFont, "SCORE: " + 99, hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);


            ////draw lives
            //for (int i = 0; i < level.Player.Lives; i++)
            //{
            //    spriteBatch.Draw(level.Player.LifeTexture, new Rectangle(i * 25 + 10, 65, (int)(level.Player.LifeTexture.Width * .35), (int)(level.Player.LifeTexture.Height * .35)), Color.White);
            //}

            for (int i = 0; i < Bomberman.Instance.EntityManager.Players.Count; i++)
            {
                DrawShadowedString(spriteBatch, hudFont, Bomberman.Instance.EntityManager.Players[i].ClientName + ": " +
                    Bomberman.Instance.EntityManager.Players[i].NetworkId, hudLocation + new Vector2(150, i * 20), Color.Yellow);
            }

            // Determine the status overlay message to show.
            Texture2D status = null;
            if (level.TimeRemaining == TimeSpan.Zero)
            {
                if (level.IsFinished)
                {
                    status = winOverlay;
                }
                else
                {
                    status = loseOverlay;
                }
            }

            if (status != null)
            {
                // Draw status message.
                Vector2 statusSize = new Vector2(status.Width, status.Height);
                spriteBatch.Draw(status, center - statusSize / 2, Color.White);
            }
        }

        private void DrawShadowedString(SpriteBatch spriteBatch, SpriteFont font, string value, Vector2 position, Color color)
        {
            spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
            spriteBatch.DrawString(font, value, position, color);
        }
    }
}
